package com.zx.flow.api.sdk.v1;


import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.zx.flow.api.exception.FlowException;
import com.zx.flow.api.sdk.IFlowSdk;
import com.zx.flow.api.util.JWTUtil;
import com.zx.flow.api.util.Util;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

@Data
@AllArgsConstructor
@Slf4j
public abstract class AbstractFlowSdk implements IFlowSdk {

    private static final int[] REPLAY_LEVEL_TIME = {1 * 1000, 5 * 1000, 10 * 1000, 30 * 1000, 60 * 1000};

    /**
     * 验签信息
     */
    private FlowSecretInfo secret;

    /**
     * sdk环境配置
     */
    private FlowSdkProfile profile;

    public String token() {
        String secretId = this.secret.getSecretId();
        String secretKey = this.secret.getSecretKey();
        String token = JWTUtil.generateToken(secretId, secretKey, secretId);
        return token;
    }

    public <T> T post(Object param, String uri, Class<T> clazz) {
        String post = this.post(param, uri);
        if (StringUtils.isEmpty(post)) {
            return null;
        }
        T t = Util.getJavaObject(post, clazz);
        return t;
    }

    public String post(Object param, String uri) {
        for (int i = 0; i < this.profile.getReplay(); i++) {
            try (HttpResponse httpResponse = HttpUtil
                    .createPost(this.profile.getProtocol() + "" + this.profile.getHost() + uri)
                    .header("Authorization", this.token())
                    .header("secretId", this.secret.getSecretId())
                    .header("Content-Type", "application/json;charset=UTF-8")
                    .setConnectionTimeout(this.profile.getConnTimeout())
                    .setReadTimeout(this.profile.getReadTimeout())
                    // 将流程对象发送过去
                    .body(Util.getJsonStr(param))
                    .execute()
            ) {
                if (httpResponse.isOk()) {
                    String body = httpResponse.body();
                    return body;
                } else {
                    log.error("flowSdk, 调用失败, 重试次数={}/{}, status={}, response={}",
                            i, this.profile.getReplay(), httpResponse.getStatus(), httpResponse.body());
                }
            } catch (Exception e) {
                log.error("flowSdk, 调用出现异常", e);
            }
            ThreadUtil.safeSleep(REPLAY_LEVEL_TIME[i]);
        }
        throw new FlowException("flowSdk, 调用失败, 重试" + this.profile.getReplay() + "次");
    }

}